//todo 上传文件
import 'dart:io';
import 'dart:typed_data';

import 'package:star_author/controller/app_package_info_getx_controller.dart';
import 'package:star_author/env/env_config.dart';
import 'package:star_author/provider/user.dart';
import 'package:star_author/utils/common_util/log_util.dart';
import 'package:star_author/utils/common_util/toast/custom_toast.dart';
import 'package:star_author/utils/event.dart';
import 'package:star_author/utils/utils.dart';
import 'package:dio/dio.dart';
import 'package:dio_log/dio_log.dart';
import 'package:flutter/foundation.dart';
import 'package:get/get.dart' as getx;
import 'package:md5_file_checksum/md5_file_checksum.dart';
import 'package:package_info/package_info.dart';
import 'package:provider/provider.dart';

import 'http_util.dart';

class UploadFileUtil {
  static const String content_type_image = "image/jpg";

  static const String content_type_video = "video/mp4";

  static const String error_event_name = "upload_error";

  static Future upload(
    String path,
    Function(Map<String, dynamic>) toUpload, {
    String content_type: content_type_image,
  }) async {
    File file = File(path);
    int size = file.lengthSync(); //文件大小
    //大于20M不上传 并且提醒
    if (content_type == content_type_image) {
      if (size > 1024 * 1024 * 20) {
        CustomToast.show('图片超过20M上传限制!');
        return;
      }
    }
    String checksum = await Md5FileChecksum.getFileChecksum(filePath: path);
    HttpUtil.commonRequest(
      getx.Get.context!,
      '/api/v1/upload_directly_meta_information',
      queryParameters: {
        "filename": path,
        "content_type": content_type,
        "byte_size": size,
        "checksum": checksum,
      },
      method: HttpUtil.MethodPost,
      isLoading: false,
      isCatchErrorLogin: false,
      isErrorToast: false,
      timeout: 120,
    ).then((value) async {
      Map headers = value.data['headers'];
      Dio dio = Dio()
        ..options = BaseOptions(
          connectTimeout: 999999,
          receiveTimeout: 999999,
          sendTimeout: 999999,
          headers: {
            "X-Authorization": getUserToken(),
            'X-APP-VERSION': getVersion(),
            'Accept': "*/*",
            'Content-Length': size.toString(),
            'Connection': 'keep-alive',
            ...headers
          },
          // contentType: lookupMimeType(path),
        );
      if (!EnvConfig.isProd() || kDebugMode) {
        dio.interceptors.add(
          LogInterceptor(requestBody: true, responseBody: true),
        );
        dio.interceptors.add(DioLogInterceptor());
      }
      String uploadUrl = value.data['url'];
      dynamic signed_id = value.data['signed_id'];
      dynamic service_url = value.data['service_url'];
      Map<String, dynamic> map = {
        'path': path,
        'signed_id': signed_id,
        "upload_success": false,
        "image_url": service_url,
      };
      if (content_type == content_type_video) {
        Uint8List uint = await getThumbnail(path, 500, 500); //视频缩略图
        //去上传的时候 回调参数给页面  然后刷新页面
        map['imageBytes'] = uint;
      } else {
        map['imageBytes'] = file.readAsBytesSync();
      }
      final request = dio.put(
        uploadUrl,
        data:
            (await MultipartFile.fromFile(path, filename: path)).finalize(), //
        onSendProgress: (int sent, int total) {
          LogUtil.v("sent:$sent,total:$total");
          // LogUtil.v("当前进度:${(sent / total) * 100}% 当前上传:${formatFileSize(sent)} ,总共${formatFileSize(total)}");
        },
      ).catchError((e) {
        Event.emit(error_event_name, {
          "signed_id": signed_id,
        });
        LogUtil.v("上传失败:${e.toString()}");
      });
      map['request'] = request;
      toUpload(map);
    }).catchError((e) {
      Event.emit(error_event_name, {
        "upload_directly_meta_information": true,
      });
    });
  }

  //获取APP版本号
  static Future<String> getVersion() async {
    PackageInfo? packageInfo =
        getx.Get.find<AppPackageInfoGetXController>().packageInfo;
    return packageInfo?.version ?? "";
  }

  //用户token
  static String getUserToken() {
    return Provider.of<UserProvider>(getx.Get.context!, listen: false).token ??
        "";
  }

  //直传然后有返回的接口
  static Future uploadSync(
    String path,
    Function(Map<String, dynamic>) uploadSuccess, {
    String content_type: content_type_image,
  }) async {
    File file = File(path);
    int size = file.lengthSync(); //文件大小
    String checksum = await Md5FileChecksum.getFileChecksum(filePath: path);
    HttpUtil.commonRequest(
      getx.Get.context!,
      '/api/v1/upload_directly_meta_information',
      queryParameters: {
        "filename": path,
        "content_type": content_type,
        "byte_size": size,
        "checksum": checksum,
      },
      method: HttpUtil.MethodPost,
      isLoading: false,
      isCatchErrorLogin: false,
      isErrorToast: false,
      timeout: 120,
    ).then((value) async {
      Map headers = value.data['headers'];
      Dio dio = Dio()
        ..options = BaseOptions(
          connectTimeout: 999999,
          receiveTimeout: 999999,
          sendTimeout: 999999,
          headers: {
            "X-Authorization": getUserToken(),
            'X-APP-VERSION': getVersion(),
            'Accept': "*/*",
            'Content-Length': size.toString(),
            'Connection': 'keep-alive',
            ...headers
          },
          // contentType: lookupMimeType(path),
        );
      if (!EnvConfig.isProd() || kDebugMode) {
        dio.interceptors.add(
          LogInterceptor(requestBody: true, responseBody: true),
        );
        dio.interceptors.add(DioLogInterceptor());
      }
      String uploadUrl = value.data['url'];
      dynamic signed_id = value.data['signed_id'];
      dynamic service_url = value.data['service_url'];
      Map<String, dynamic> map = {
        'path': path,
        'signed_id': signed_id,
        "upload_success": false,
        "image_url": service_url,
      };
      if (content_type == content_type_video) {
        Uint8List uint = await getThumbnail(path, 500, 500); //视频缩略图
        //去上传的时候 回调参数给页面  然后刷新页面
        map['imageBytes'] = uint;
      } else {
        map['imageBytes'] = file.readAsBytesSync();
      }
      await dio.put(
        uploadUrl,
        data:
            (await MultipartFile.fromFile(path, filename: path)).finalize(), //
        onSendProgress: (int sent, int total) {
          LogUtil.v("sent:$sent,total:$total");
          // LogUtil.v("当前进度:${(sent / total) * 100}% 当前上传:${formatFileSize(sent)} ,总共${formatFileSize(total)}");
        },
      ).then((value) {
        uploadSuccess(map);
      }).catchError((e) {
        Event.emit(error_event_name, {
          "signed_id": signed_id,
        });
        LogUtil.v("上传失败:${e.toString()}");
      });
    }).catchError((e) {
      Event.emit(error_event_name, {
        "upload_directly_meta_information": true,
      });
    });
  }
}
